/**************************************
 * js验证工具方法
 * 此工具包依赖CommonUtils.js、DateUtils.js
 * @author Xiaopeng
 * @date 2014-07-15
 **************************************/

/**
 * 校验ip地址的格式
 * @param strIP：ip地址 
 * @returns 如果通过验证返回true,否则返回false
 */
function isIP(strIP) { 
	if (isNull(strIP)) return false; 
	//匹配IP地址的正则表达式 
	var re=/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/g 
	if(re.test(strIP)) { 
		if( RegExp.$1 <256 && RegExp.$2<256 && RegExp.$3<256 && RegExp.$4<256) return true; 
	} 
	return false; 
} 

function isURL(str_url) { 
	var strRegex = '^((https|http|ftp|rtsp|mms)?://)' 
		+ '?(([0-9a-z_!~*\'().&=+$%-]+: )?[0-9a-z_!~*\'().&=+$%-]+@)?' //ftp的user@ 
		+ '(([0-9]{1,3}.){3}[0-9]{1,3}' // IP形式的URL- 199.194.52.184 
		+ '|' // 允许IP和DOMAIN（域名） 
		+ '([0-9a-z_!~*\'()-]+.)*' // 域名- www. 
		+ '([0-9a-z][0-9a-z-]{0,61})?[0-9a-z].' // 二级域名 
		+ '[a-z]{2,6})' // first level domain- .com or .museum 
		+ '(:[0-9]{1,4})?' // 端口- :80 
		+ '((/?)|' // a slash isn't required if there is no file name 
		+ '(/[0-9a-z_!~*\'().;?:@&=+$,%#-]+)+/?)$'; 
	var re=new RegExp(strRegex); 
	if (re.test(str_url)) { 
		return true; 
	}
	return false;
} 

/**
 * 检查输入字符串是否为空或者全部都是空格 
 * @param str
 * @returns 如果全是空返回true,否则返回false 
 */
function isNull(str) { 
	return CommonUtils.isNull(str); 
} 

/**
 * 检查输入对象的值是否符合整数格式
 * @param str
 * @returns 如果通过验证返回true,否则返回false
 */
function isInteger(str) {  
	return CommonUtils.isInteger(str); 
} 

/**
 * 检查输入手机号码是否正确
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isMobile(str) {
	var regex = /^1[3|4|5|8][0-9]\d{4,8}$/; 
	var re = new RegExp(regex); 
	if(str.length==11 && re.test(str)) { 
		return true; 
	}
	return false; 
} 

/**
 * 检查输入字符串是否符合纯数字格式 
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false 
 */
function isNumber(str) {   
	return CommonUtils.isNumber(str); 
} 

/**
 * 检查输入字符串是否符合正整数格式
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isPositiveInteger(str) {
	return CommonUtils.isPositiveInteger(str); 
}

/**
 * 检查输入字符串是否符合负整数格式
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isNegativeInteger(str) {
	return CommonUtils.isNegativeInteger(str); 
}

/**
 * 检查输入字符串是否符合整数格式，包含负整数，但不包含0
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isIntegerExcept0(str) {
	return CommonUtils.isIntegerExcept0(str); 
}

/**
 * 检查输入字符串是否符合整数格式，包含负整数和0
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isIntegerContains0(str) {
	return CommonUtils.isIntegerContains0(str); 
}

/**
 * 检查输入字符串是否符合浮点数格式，包含负浮点数和0
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isFloat(str) {   
	return CommonUtils.isFloat(str);
} 

/**
 * 检查输入字符串是否符合正浮点数格式
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isPositiveFloat(str) {   
	return CommonUtils.isPositiveFloat(str);
} 

/**
 * 检查输入字符串是否符合负浮点数格式
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isNegativeFloat(str) {   
	return CommonUtils.isNegativeFloat(str);
}

/**
 * 检查输入对象的值是否符合端口号格式
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isPort(str) {  
	return (isPositiveInteger(str) && str<65536); 
}

/**
 * 检查输入对象的值是否符合E-Mail格式 
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isEmail(str) {  
	var myReg = /^[-_A-Za-z0-9]+@([_A-Za-z0-9]+\.)+[A-Za-z0-9]{2,3}$/; 
	if(myReg.test(str)) {
		return true;
	} 
	return false; 
} 

/**
 * 检查输入字符串是否符合金额格式 
 * 格式定义为带小数的正数，小数点后最多三位
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isMoney(str) {   
	var regu = "^[1-9]([0-9]+)[\.][0-9]{0,3}$"; 
	var re = new RegExp(regu); 
	if (re.test(str)) { 
		return true; 
	}
	return false;
} 

/**
 * 检查输入字符串是否只由英文字母和数字和下划线组成 
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isNumberOr_Letter(str){
	return CommonUtils.isNumberOr_Letter(str);
}

/**
 * 检查输入字符串是否只由英文字母和数字组成
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isNumberOrLetter(str){
	return CommonUtils.isNumberOr_Letter(str);
} 

/**
 * 检查输入字符串是否只由汉字、字母、数字组成
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isChinaOrNumbOrLett(str){ 
	return CommonUtils.isChinaOrNumbOrLett(str);
} 

/**
 * 检查输入字符串是否只由汉字、字母、数字、下划线组成
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isChinaOrNumbOr_Lett(str){ 
	return CommonUtils.isChinaOrNumbOr_Lett(str);
}

/**
 * 检查输入字符串是否只由汉字、字母、数字、中划线组成
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isChinaOrNumbLettOrDash(str){ 
	return CommonUtils.isChinaOrNumbLettOrDash(str);
}

/**
 * 检查是否通用的日期格式，如2014-07-19或2014-7-19
 * @param date
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isSimpleDate(date) {
	return DateUtils.isSimpleDate(date);
}

/**
 * 检查是否通用的日期时间格式，如：2014-07-30 15:52:00
 * @param dateTime
 * @returns {Boolean}
 */
function isChinaDateTime(dateTime) {
	return DateUtils.isChinaDateTime(dateTime);
}

/**
 * 判断是否是日期
 * @param date 日期
 * @param fmt 日期格式
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isDate(date, fmt) { 
	return DateUtils.isDate(date, fmt); 
} 

/**
 * 检查输入的电话号码格式是否正确
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isPhone(str) {
	var regex = /^(d{3,4}-?)?d{7,9}$/g; 
	var re = new RegExp(regex); 
	if(re.test(str)) { 
		return true; 
	}
	return false;
}

/**
 * 检查证券代码是否正确
 * @param bondCode 证券代码，格式为6位数字
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isBondCode(bondCode) { 
	if(bondCode.length != 6){ 
		return false; 
	} 
	if(!CommonUtils.isNumber(bondCode)){ 
		return false; 
	} 
	return true; 
} 

/**
 * (1)身份证15位编码规则：dddddd yymmdd xx p 
 * dddddd：地区码 
 * yymmdd: 出生年月日 
 * xx: 顺序类编码，无法确定 
 * p: 性别，奇数为男，偶数为女
 * 
 * (2)身份证18位编码规则：dddddd yyyymmdd xxx p y 
 * dddddd：地区码 
 * yyyymmdd: 出生年月日
 * xxx:顺序类编码，无法确定，
 * p: 性别，奇数为男，偶数为女 
 * y: 校验码，该位数值可通过前17位计算获得
 * 18位号码加权因子为(从右到左) Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2,1 ]
 * 验证位 Y = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ] 
 * 校验位计算公式：Y_P = mod( ∑(Ai×Wi),11 )
 * i为身份证号码从右往左数的 2...18 位; Y_P为脚丫校验码所在校验码数组位置
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */  
var Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 ];// 加权因子
var ValideCode = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ];// 身份证验证位值.10代表X
function isIdCardValidate(idCard) {   
    idCard = CommonUtils.trim(idCard.replace(/ /g, ""));   
    if(idCard.length == 15) {   
        return isValidityBrithBy15IdCard(idCard);   
    } else if (idCard.length == 18) {   
        var a_idCard = idCard.split("");// 得到身份证数组
        if(isValidityBrithBy18IdCard(idCard) && isTrueValidateCodeBy18IdCard(a_idCard)) {   
            return true;   
        }
        return false;
    }
    return false;
}

/**
 * 验证15位数身份证号码中的生日是否是有效生日
 * @param idCard15 15位书身份证字符串
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */  
function isValidityBrithBy15IdCard(idCard15){   
	var year =  idCard15.substring(6,8);   
    var month = idCard15.substring(8,10);   
    var day = idCard15.substring(10,12);   
    var temp_date = new Date(year,parseFloat(month)-1,parseFloat(day));   
    // 对于老身份证中的你年龄则不需考虑千年虫问题而使用getYear()方法
    if(temp_date.getYear()!=parseFloat(year)   
    		||temp_date.getMonth()!=parseFloat(month)-1   
            ||temp_date.getDate()!=parseFloat(day)){   
    	return false;   
    }else{   
        return true;   
    }   
}   

/**
 * 验证18位数身份证号码中的生日是否是有效生日
 * @param idCard 18位书身份证字符串
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */  
function isValidityBrithBy18IdCard(idCard18){   
    var year =  idCard18.substring(6,10);   
    var month = idCard18.substring(10,12);   
    var day = idCard18.substring(12,14);   
    var temp_date = new Date(year,parseFloat(month)-1,parseFloat(day));   
    // 这里用getFullYear()获取年份，避免千年虫问题
    if(temp_date.getFullYear()!=parseFloat(year)   
          ||temp_date.getMonth()!=parseFloat(month)-1   
          ||temp_date.getDate()!=parseFloat(day)){   
            return false;   
    }else{   
        return true;   
    }   
}

/**
 * 判断身份证号码为18位时最后的验证位是否正确
 * @param a_idCard 身份证号码数组
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */  
function isTrueValidateCodeBy18IdCard(a_idCard) {   
    var sum = 0; // 声明加权求和变量
    if (a_idCard[17].toLowerCase() == 'x') {   
        a_idCard[17] = 10;// 将最后位为x的验证码替换为10方便后续操作
    }   
    for ( var i = 0; i < 17; i++) {   
        sum += Wi[i] * a_idCard[i];// 加权求和
    }   
    valCodePosition = sum % 11;// 得到验证码所位置
    if (a_idCard[17] == ValideCode[valCodePosition]) {   
        return true;   
    } else {   
        return false;   
    }   
}

/**
 * 检查字符串是否包含特殊字符
 * @param str
 * @returns {Boolean} 如果通过验证返回true,否则返回false
 */
function isContainSpecChar(str) { 
	return CommonUtils.isContainSpecChar(str);
} 

/**
 * 检查字符串是否不包含特殊字符：' " \
 * @param str
 * @returns {Boolean} 如果不包含特殊字符则返回true,否则返回false
 */
function isNoContainSpecialChar(str) {
	return CommonUtils.isNoContainSpecialChar(str);
}
